package com.zsk.shop.common.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.zsk.shop.common.base.BaseResponse;
import com.zsk.shop.common.constant.Constant;
import com.zsk.shop.common.enums.EnumQRCodeType;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;

/**
 * Created by zhangws on 2020/4/13 15:44.
 */
@Component
public class ImageUtil {

    private final static Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    /*
        //ali:
        //  oss:
        //    accessKeyId: LTAI4G9QCReRd1vMXhtdsNNa
        //    accessKeySecret: 644wmLzVww9dof1KqZu1ve63lEnhhS
        //    endpoint: "http://oss-cn-hangzhou.aliyuncs.com"
        //    bucketName: yulink */
    // OOS地址 Endpoint以杭州为例，其它Region请按实际情况填写
    private final static String endpoint = "oss-ap-southeast-1.aliyuncs.com";
    private final static String accessKeyId = "LTAI5tAkHEknHSzS2BBw7jGr";
    private final static String accessKeySecret = "1xqsXV55emT2kjBAbUMrt8YlonsAxT";
    private static String bucketName = "zhishangke";

    //将本地图片转换为base64
    public static String localImageToBase64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        String result = Base64.encodeBase64String(data);
        // 返回Base64编码过的字节数组字符串
        return result;
    }

    //将网络地址对应的图片转换为base64
    public static String imageToBase64(String imagePath) {
        if (!imagePath.contains("https")) {
            imagePath = imagePath.replaceAll("http", "https");
        }
        ByteArrayOutputStream outPut = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        try {
            // 创建URL
            URL url = new URL(null, imagePath, new sun.net.www.protocol.https.Handler());
            // 创建链接
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(10 * 1000);
            if (conn.getResponseCode() != sun.net.www.protocol.http.HttpURLConnection.HTTP_OK) {
                return "fail";//连接失败/链接失效/图片不存在
            }
            InputStream inStream = conn.getInputStream();
            int len = -1;
            while ((len = inStream.read(data)) != -1) {
                outPut.write(data, 0, len);
            }
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        return Base64.encodeBase64String(outPut.toByteArray());
    }

    /**
     * 判断文件大小
     *
     * @param len  文件长度
     * @param size 限制大小
     * @param unit 限制单位（B,K,M,G）
     * @return
     */
    public static boolean checkFileSize(Long len, int size, String unit) {
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        if (fileSize > size) {
            return false;
        }
        return true;
    }

    /**
     * 直接把上传
     *
     * @return
     */
    public static String ossUpload(InputStream file) {
        String date = DateUtils.format(new Date(), DateUtils.YYYYMMDD_SIMPLE);
        String dateStr = DateUtils.format(new Date(), DateUtils.YYYYMMDDHHMMSS1);
        String pictureName = "img/chn/" + date + "/" + UUID.randomUUID().toString() + dateStr + ".png";
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流。
        ossClient.putObject(bucketName, pictureName, file);
        // 关闭OSSClient。
        ossClient.shutdown();
        return "https://oss.zhishangkeapp.com/" + pictureName;
    }

    public static void saveFile(MultipartFile filecontent) {
        OutputStream os = null;
        InputStream inputStream = null;
        String fileName = null;
        try {
            inputStream = filecontent.getInputStream();
            fileName = filecontent.getOriginalFilename();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            String path = "C:\\test\\";
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * UTC时间转换为当地时间
     *
     * @param utcTime UTC时间
     * @return 北京时间
     */
    private static String convertTime(String utcTime) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        //设置时区UTC
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        //格式化，转当地时区时间
        Date after = null;
        try {
            after = df.parse(utcTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return DateUtils.format(after);
    }

    public static BaseResponse ossUpload(MultipartFile file, String accessKeyId, String accessKeySecret, String securityToken) {
        System.out.println("文件信息：" + file + "============" + "其他参数：" + accessKeyId + "其他参数：" + accessKeySecret);
        String filename = file.getResource().getFilename();
        //这里文件名用了uuid 防止重复，可以根据自己的需要来写
        String name = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."), filename.length());
        name = name.replace("-", "");
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("上传失败");
        }
        //开启ossClient;
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken);
        //上传图片
        try {
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(inputStream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(name.substring(name.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + name);
            // 指定上传文件操作时是否覆盖同名Object。
            // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
            // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
            // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
            objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
            //文件前缀
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
            String nowDate = sdf1.format(new Date());
            System.out.println("当前日期是：" + nowDate);
            String filedir = "tbd/" + nowDate + "/";
            String objectName = filedir + name;
            //上传文件
            ossClient.putObject(bucketName, objectName, inputStream, objectMetadata);
            // 封装  url 路径
            String url = "https://oss.zhishangkeapp.com/" + objectName;
            System.out.println(objectName);
            return BaseResponse.success(url);
        } catch (IOException e) {
            System.out.println("错误信息：" + e.getMessage());
        } finally {
            ossClient.shutdown();
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return BaseResponse.success();
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
                "jpg".equalsIgnoreCase(FilenameExtension) ||
                "png".equalsIgnoreCase(FilenameExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
                "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) ||
                "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        return "image/jpeg";
    }


    /**
     * 上传视频
     *
     * @return
     */
    public String ossUploadVideo(InputStream file) {
        String date = DateUtils.format(new Date(), DateUtils.YYYYMMDD_SIMPLE);
        String dateStr = DateUtils.format(new Date(), DateUtils.YYYYMMDDHHMMSS1);
        String videoName = "video/chn/" + date + "/" + UUID.randomUUID().toString() + dateStr + ".mp4";
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流。
        ossClient.putObject(bucketName, videoName, file);
        // 关闭OSSClient。
        ossClient.shutdown();
        return "https://oss.zhishangkeapp.com/" + videoName;
    }

    /**
     * 上传文件
     *
     * @return
     */
    public static String ossUploadFile(InputStream file, String fileName) {
        String date = DateUtils.format(new Date(), DateUtils.YYYYMMDDHHMMSS1);
        String userNo = HttpContext.getSafeUserNo();
        fileName = "file/" + userNo + "/" + date + "/" + fileName;
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流。
        ossClient.putObject(bucketName, fileName, file);
        // 关闭OSSClient。
        ossClient.shutdown();
        return "https://oss.zhishangkeapp.com/" + fileName;
    }

    /**
     * 上传图片到OSS
     *
     * @param file
     * @param fileName
     * @return
     */
    public static String ossUploadFileName(InputStream file, String fileName) {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流。
        ossClient.putObject(bucketName, fileName, file);
        // 关闭OSSClient。
        ossClient.shutdown();
        return "https://oss.zhishangkeapp.com/" + fileName;
    }

    /**
     * 简单上传图片：根据图片路径保存图象。
     * author ljh
     * 2018年12月17日19:27:38
     *
     * @return
     */
    public Boolean ossUploadPhoto(String file, String fileName) {
        try {
            // 创建OSSClient实例。
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            // 上传文件流。
            // 上传网络流。
            InputStream inputStream = new URL(file).openStream();
            ossClient.putObject(bucketName, fileName, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (IOException e) {
            e.getMessage();
            e.printStackTrace();
        }
        return true;
    }

    //对于图片文件（在未修改文件http头的情况下）：
    //若您的Bucket是2019年9月23日前创建的，使用OSS默认访问域名或自有域名生成的文件URL从浏览器访问时可以预览文件内容。
    //若您的Bucket是2019年9月23日后创建的，使用OSS默认域名生成的文件URL从浏览器访问时会以附件形式下载；
    //使用自有域名生成的文件URL访问时，可以预览文件内容。绑定自有域名步骤请参见
    //绑定自定义域名。https://help.aliyun.com/document_detail/31902.html?spm=a2c4g.11186623.2.2.552014faVd4e9e

    /**
     * 创建带图标的二维码图像
     *
     * @param content   二维码内容
     * @param code      用户是，会议是会议号
     * @param avatarUrl 二维码中图片
     * @param type      二维码类型
     */
    public static void greatQRCodeImg(String content, String code, String avatarUrl, Integer type) {
        try {
            BufferedImage image = QRCodeUtil.createImage(content, code, avatarUrl, true);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            InputStream is = new ByteArrayInputStream(os.toByteArray());
            String fileName = "img/qr_code_img/" + code + ".png";
            if (type.equals(EnumQRCodeType.TWO.getCode())) {
                fileName = "img/qr_code_img_meeting/" + code + ".png";
            }
            ossUploadFileName(is, fileName);
            logger.info("用户二维码图片生成成功!url:" + Constant.QRCODE_IMG_URL_PROD.replace("INVATECODE", code));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("生成二维码图片失败!" + code);
            return;
        }
    }

}
